﻿using System;
using Internal.KuiHuaBaoDian.Services.Battle.StateMachine;
using KuiHuaBaoDian.Services.Battle.Entity;
using KuiHuaBaoDian.Services.Battle.StateMachine;
using UnityEngine;

namespace KuiHuaBaoDian.Services.Battle.StateMachine {

    /// <summary>
    /// 指定<see cref="UnityEngine.GameObject"/>进行显示的状态机
    /// </summary>
    public interface IBattleEntityStateMachine_SingleGameObject : IBattleEntityStateMachine {

        /// <summary>
        /// 显示状态提供者
        /// </summary>
        public interface IStateProvider {

            /// <summary>
            /// 要显示的对象
            /// </summary>
            GameObject GameObject { get; }
        }
    }

    [Implement(typeof(IBattleEntityStateMachine_SingleGameObject))]
    internal sealed class KHBD_BattleEntityStateMachine_SingleGameObject : KHBD_Object, IBattleEntityStateMachine_SingleGameObject, IBattleEntityStateMachineInternal_SingleGameObject {

        private IBattleEntityAssetVehicle<IBattleEntityStateMachine_SingleGameObject.IStateProvider> m_StateVehicle;

        private GameObject m_IdleGameObject;

        public BattleEntityState State { get; set; }
        private BattleEntityState m_LastState;

        private bool m_ForceRefreshState;
        public bool IsStateChanged => State != m_LastState;

        public bool IsInitialized => m_IdleGameObject != null;

        private ParticleSystem[] m_IdleParticleSystems;

        private float m_PlaySpeed;

        void IBattleEntityStateMachineInternal_SingleGameObject.Initialize(IBattleEntityAssetVehicle<IBattleEntityStateMachine_SingleGameObject.IStateProvider> stateVehicle) {
            UnityEngine.Assertions.Assert.IsNotNull(stateVehicle);

            m_StateVehicle = stateVehicle;
            m_StateVehicle.Loaded += OnStateVehicleLoaded;
            OnStateVehicleLoaded();
        }

        protected override void Dispose() {
            m_IdleParticleSystems = null;
            m_IdleGameObject = null;
            m_StateVehicle = null;
        }

        private void OnStateVehicleLoaded() {
            if (m_StateVehicle.Content == null) {
                return;
            }

            m_IdleGameObject = m_StateVehicle.Content.GameObject;
            m_IdleGameObject.SetActive(m_LastState == BattleEntityState.Idle);
            m_ForceRefreshState = true;
            Play(m_PlaySpeed);
        }

        public void Play(float speed) {
            m_PlaySpeed = speed;

            if (!IsInitialized) {
                return;
            }
            if (State == BattleEntityState.Unknown) {
                return;
            }

            bool isStateChanged = IsStateChanged || m_ForceRefreshState;
            m_ForceRefreshState = false;
            if (isStateChanged) {
                m_IdleGameObject.SetActive(State == BattleEntityState.Idle);
                m_LastState = State;
            }

            m_IdleParticleSystems ??= m_IdleGameObject.GetComponentsInChildren<ParticleSystem>(true);

            if (m_IdleParticleSystems?.Length > 0) {
                foreach (var particleSystem in m_IdleParticleSystems) {
                    if (isStateChanged) {
                        particleSystem.Stop(false, ParticleSystemStopBehavior.StopEmittingAndClear);
                        particleSystem.Play(false);
                    }
                    var mainModule = particleSystem.main;
                    mainModule.simulationSpeed = speed;
                }
            }
        }
    }
}

namespace Internal.KuiHuaBaoDian.Services.Battle.StateMachine {

    public interface IBattleEntityStateMachineInternal_SingleGameObject : IBattleEntityStateMachine, IDisposable {

        void Initialize(IBattleEntityAssetVehicle<IBattleEntityStateMachine_SingleGameObject.IStateProvider> stateVehicle);
    }
}